/*+**************************************************************************/
/***                                                                      ***/
/***   This file is distributed under a BSD license.                      ***/
/***   See LICENSE.txt for details.                                       ***/
/***                                                                      ***/
/**************************************************************************+*/

level11;

asc
{
  cbuffer CSTestPara : register (c0) : slot cs 0
  {
    float4 tx;
    float4 ty;
    float4 ofs;
    float4 pot0;
    float4 pot1;
    float4 pot2;
    float4 pot3;
  };
}

cs CSTest
{
  asc cs_5_0
  {
    use CSTestPara;
    RWByteAddressBuffer vb : register(u0);
    RWByteAddressBuffer ib : register(u1);
    RWStructuredBuffer<uint> countbuffer : register(u2);

    [numthreads(4,4,4)]
    void main
    (
      uint3 tid : SV_GroupThreadID,
      uint3 gid : SV_GroupID
    )
    {
      uint3 id = tid+gid*4;
      float3 p = float3(id)+ofs.xyz;
      
      float pot = pot0.w/length(p-pot0.xyz)
                + pot1.w/length(p-pot1.xyz)
                + pot2.w/length(p-pot2.xyz)
                + pot3.w/length(p-pot3.xyz);
                
      float s = saturate((pot-0.6f)*8);
      if(s>0)
      {      
        float3 p0 = p + tx.xyz*s + ty.xyz*s;
        float3 p1 = p - tx.xyz*s + ty.xyz*s;
        float3 p2 = p - tx.xyz*s - ty.xyz*s;
        float3 p3 = p + tx.xyz*s - ty.xyz*s;
        
        uint n = countbuffer.IncrementCounter();
        uint vp = n*4*16;

        vb.Store4(vp+0*16+ 0,uint4(asuint(p0.xyz),(f32tof16(0)<<16)|f32tof16(0) ));
        vb.Store4(vp+1*16+ 0,uint4(asuint(p1.xyz),(f32tof16(1)<<16)|f32tof16(0) ));
        vb.Store4(vp+2*16+ 0,uint4(asuint(p2.xyz),(f32tof16(1)<<16)|f32tof16(1) ));
        vb.Store4(vp+3*16+ 0,uint4(asuint(p3.xyz),(f32tof16(0)<<16)|f32tof16(1) ));
        
        uint vi = n*4;
        uint ip = n*6*4;
        
        ib.Store4(ip   ,uint4(vi+0,vi+1,vi+2,vi+0));
        ib.Store2(ip+16,uint2(vi+2,vi+3));
      }
    }
  }
}

cs WriteCount
{
  asc cs_5_0
  {
    RWStructuredBuffer<uint> cnt : register(u0);
    RWBuffer<uint> ind : register(u1);
    [numthreads(1,1,1)]
    void main()
    {
      ind[0] = cnt.IncrementCounter()*6;
      ind[1] = 1;
      ind[2] = 0;
      ind[3] = 0;
      ind[4] = 0;
    }
  }
}

/**************************************************************************+*/

asc
{
  cbuffer MaterialFlatPara : register(c0)
  {
    row_major float4x4 mvp;
  };
}

material MaterialFlat
{
  // the vertex shader

  vs
  {    
    asc vs_5_0                 // hlsl code
    {
      use MaterialFlatPara;

      void main
      (
        in float3 in_pos : POSITION,            // input, from vertex array
        in float2 in_uv : TEXCOORD0,
        out float2 out_uv : TEXCOORD0,          // output, to pixel shader. 
        out float4 out_pos : POSITION,          // position last for DX11
      ) 
      {
        out_uv = in_uv;
        out_pos = mul(float4(in_pos,1),mvp);
      }
    }
  }

  // the pixel shader

  ps
  {

    asc ps_5_0
    {
      SamplerState sam0 : register(s0);
      Texture2D tex0 : register(t0);
      void main
      (
        in float2 uv : TEXCOORD0,
        out float4 result : COLOR0
      )
      {
        result = tex0.Sample(sam0,uv);
      }
    }
  }
};
